package com.sen.uaa.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.sen.common.common.bo.PeopleInfo;
import com.sen.common.common.bo.SysAccountBO;
import com.sen.common.common.bo.SysResourceBO;
import com.sen.common.common.bo.User;
import com.sen.common.common.response.MessageResult;
import com.sen.rbac.feign.RbacAccountFeign;
import com.sen.rbac.feign.RbacResourceFeign;
import com.sen.uaa.config.ParamsContextHolder;
import com.sen.uaa.exception.UaaException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
   * @Description 用户服务-提供认证服务器使用
   * @author esjiang
**/
@Service
@Slf4j
public class UserServiceImpl implements UserDetailsService, Serializable {

    @Resource
    transient RbacAccountFeign rbacAccountFeign ;

    @Resource
    transient RbacResourceFeign rbacResourceFeign ;

    private static final String CHAR_REPLACE = "#" ;

    private static final String TENANT_CODE = "tenantCode" ;

    private static final String ENTITY_TYPE = "entityType" ;

    private static final String SYSTEM_CODE = "systemCode" ;

    public UserDetails loadUserByKeyNum(String keyNum){
        /** 加载人员信息 */
        MessageResult result = MessageResult.success();
        if (checkResult(result)){
            String userName = Convert.toStr(result.getBody().getData());
            return loadUserByUsername(userName);
        }
        return null ;
    }

    @Override
    public UserDetails loadUserByUsername(String userName) throws UsernameNotFoundException {
        Map<String, String> params = ParamsContextHolder.getParams();
        MessageResult<SysAccountBO> messageResult = rbacAccountFeign.selectAccountByUserNameForGateway(userName,Convert.toStr(params.get(TENANT_CODE),""),params.get(SYSTEM_CODE));

        if (null == messageResult || !messageResult.getHead().getSuccess().booleanValue() || !messageResult.getBody().getSuccess().booleanValue() ){
            throw new UaaException(MessageResult.build(messageResult)) ;
        }
        SysAccountBO authSysUser = messageResult.getBody().getData();
        if (ObjectUtil.isNull(authSysUser)){
            throw new UsernameNotFoundException(String.valueOf(500)) ;
        }
        User user = new User() ;
        user.setSysAccount(authSysUser);
        List<SimpleGrantedAuthority> simpleGrantedAuthorities = new ArrayList<>() ;
        MessageResult<List<SysResourceBO>> authorityResult = rbacResourceFeign.findResourceByUserNameForGateway(userName);
        if( null == authorityResult || !authorityResult.getHead().getSuccess().booleanValue() || !authorityResult.getBody().getSuccess().booleanValue()){
            user.setSimpleGrantedAuthorities(simpleGrantedAuthorities);
            return user ;
        }
        List<SysResourceBO> info = authorityResult.getBody().getData();
        if( null != info ){
            for (SysResourceBO authority : info) {
                SimpleGrantedAuthority simpleGrantedAuthority = null ;
                if (StrUtil.isBlank(authority.getUrl())){
                    simpleGrantedAuthority = new SimpleGrantedAuthority(CHAR_REPLACE) ;
                }else {
                    simpleGrantedAuthority = new SimpleGrantedAuthority(authority.getUrl()) ;
                }
                simpleGrantedAuthorities.add(simpleGrantedAuthority) ;
            }
        }
        user.setSimpleGrantedAuthorities(simpleGrantedAuthorities);
        /** 加载人员信息 */
        MessageResult<PeopleInfo> result = null ;//memberPeopleFeign.getPeopleInfoByLogin(userName);
        if (checkResult(result)){
            user.setPeopleInfo(result.getBody().getData());
        } else {
            user.setPeopleInfo(new PeopleInfo());
        }
        user.getPeopleInfo().setEntityType(Convert.toStr(params.get(ENTITY_TYPE)));
        user.getPeopleInfo().setEntityCode(authSysUser.getEntityCode());
        user.getPeopleInfo().setRoleCodes(authSysUser.getRoleCodes());
        return user;
    }

    private boolean checkResult(MessageResult result){
        if (ObjectUtil.isNotNull(result) && ObjectUtil.isNotNull(result.getBody()) && ObjectUtil.isNotNull(result.getHead())) {
            if (result.getHead().getSuccess().booleanValue() && result.getBody().getSuccess().booleanValue() && ObjectUtil.isNotNull(result.getBody().getData())) {
                return true ;
            }
        }
        return false ;
    }

}
